#pragma once
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <future>
#include <iostream>
#include <map>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>

using namespace std;
class ThreadPool {
 public:
  // 构造函数:直接获取CPU的核心数作为线程池的最大线程数
  ThreadPool(int min = 2, int max = thread::hardware_concurrency());
  ~ThreadPool();

  // 添加任务->任务队列
  void addTask(function<void(void)> task);

  // 模版函数

  template <class F, class... Args>

  private : void manager(void);  // 线程管理器
  void worker(void);             // 线程工作者

 private:
  thread *m_manager;                  // 线程管理器
  map<thread::id, thread> m_workers;  // 线程池
  vector<thread::id> m_ids;   // 储存已经退出任务函数的线程ID
  atomic<int> m_minThread;    // 最小线程数
  atomic<int> m_maxThread;    // 最大线程数
  atomic<int> m_curThreads;   // 当前线程数
  atomic<int> m_idleThreads;  // 空闲线程数
  atomic<int> m_exitThreads;  // 退出线程数
  atomic<bool> m_stop;        // 线程池停止标志

  queue<function<void()>> m_tasks;  // 任务队列：存储任务的可调用对象
  mutex m_queueMutex;               // 线程互斥锁
  mutex m_idsMutex;                 // 线程ID互斥锁
  condition_variable m_condition;  // 条件变量
};